<?php

namespace App\Http\Controllers;

use App\Address;
use App\Aged;
use App\Cart;
use App\Mall;
use App\Order;
use App\Product;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use App\Exports\OrderExport;
use Maatwebsite\Excel\Facades\Excel;
use App\Http\Controllers\Traits\CheckPermissions;

class OrderController extends Controller
{
    use CheckPermissions;

    //订单首页
    public function index()
    {
        $orders = Order::where('user_id', Auth::id())->OrderBy('created_at', 'DESC')->paginate(10);
        foreach ($orders as $key => $value) {
            $products = json_decode($value->products);
            foreach ($products as $k => $val) {
                $orders[$key]['pro_text'] .= '[' . $val->product->name . '×' . $val->total_num . ']';
            }
        }
        return view('home.order.index', compact('orders'));
    }

    //选购界面
    public function create($mall_id)
    {
        $mall = Cache::remember('mall_' . $mall_id, 86400, function () use ($mall_id) {
            return Mall::find($mall_id);
        });

        $this->check_result($mall);
        $is_admin=$this->is_mall_admin($mall_id);

        $address = Cache::remember('address_' . Auth::id(), 86400 * 7, function () {
            return Address::where('user_id', Auth::id())->get();
        });

        if ($address->count() == 0) {
            return redirect(route('address.index'))->with('success', '请先添加姓名、电话、楼栋号码再购物。');
        }

        if ($address->count() > 1) {
            return redirect(route('address.index'))->with('success', '您有多个收货信息，请删除多余的信息。【请务必保留含有楼栋号码的信息】');
        }

        if ($address->count() == 1) {
            $home_number = Cache::remember('address_first_' . Auth::id(), 86400 * 7, function () {
                return Address::where('user_id', Auth::id())->first()->home_number;
            });
            if ($home_number == '' || is_null($home_number)) {
                return redirect(route('address.index'))->with('success', '你没有完善楼栋号码，请完善后再购物。【删除收货信息重新填写】');
            }
        }

        //商品
        $products = Cache::remember('product_' . $mall_id, 30, function () use ($mall_id) {
            return Product::where('is_show', 1)->where('mall_id', $mall_id)->where('is_putaway', 1)->get();
        });

        return view('home.order.create', compact('products', 'mall','is_admin'));
    }

    //提交订单
    public function store(Request $request)
    {
        $mall_id = $request->input('mall_id');
        $is_show = Cache::remember('mall_' . $mall_id, 86400, function () use ($mall_id) {
            return Mall::find($mall_id);
        })->is_show;

        $is_admin=$this->is_mall_admin($mall_id);

        //管理员不受系统开关限制
        if (!$is_show && !$is_admin) {
            return back()->with('success', '系统已经关闭,订单提交失败!!!');
        }
        $carts = Cart::where('user_id', Auth::id())->where('mall_id', $mall_id)->get();
        if ($carts->count() == 0) {
            return back()->with('success', '购物车为空,订单提交失败!!!');
        }

        //购物车总金额
        try {
            $total_price = 0;
            foreach ($carts as $key => $value) {
                $total_price += $value->product->money * $value->total_num;
            }
        } catch (\Exception $exception) {
            return back()->with('success', '您的购物车中有失效的商品,请删除后重新提交订单!!!');
        }

        $is_admin = $this->is_mall_admin($mall_id);

        //是否为代买模式 只允许管理员代买
        $aged_id = $request->input('aged_id');
        if ($aged_id != 0 && $is_admin) {
            $address = Aged::find($aged_id);
            $data['name'] = $address->name;
            $data['tel'] = $address->tel;
        } else {
            $address = Address::where('user_id', Auth::id())->first();
            $data['name'] = $address->name;
            $data['tel'] = $address->tel;
        }

        $data['user_id'] = Auth::id();
        $data['products'] = json_encode($carts->toArray());
        $data['total_money'] = $total_price;
        $data['total_num'] = array_sum($carts->pluck('total_num')->toArray());
        $data['mall_id'] = $mall_id;
        try {
            $order = DB::transaction(function () use ($data, $mall_id, $carts) {
                //创建订单
                $order = Order::create($data);
                //减商品对应的库存
                foreach ($carts as $cart) {
                    $product = Product::lockForUpdate()->find($cart->product_id);
                    $product->decrement('stock', $cart->total_num);
                    //如果库存为负数则抛出异常
                    if ($product->stock < 0) {
                        throw new \Exception('当前商品' . $product->name . '库存不足，提交订单失败!');
                    }
                }
                //清空购物车
                Cart::where('user_id', Auth::id())->where('mall_id', $mall_id)->delete();
                return $order;
            }, 5);
        } catch (\Exception $exception) {
            return back()->with('success', '提交订单失败!!!!!' . $exception->getMessage());
        }
        return redirect(route('order.show', $order->id))->with('pay_success', '提交订单成功');
    }

    //显示订单
    public function show($id)
    {
        $order = Order::with('mall')->where('user_id', Auth::id())->where('id', $id)->first();
        $products = json_decode($order->products);
        $pro_text = null;
        foreach ($products as $key => $value) {
            $pro_text .= '[' . $value->product->name . '×' . $value->total_num . ']';
        }
        return view('home.order.show', compact('order', 'pro_text'));
    }

    //确认收货
    public function success(Request $request, $id)
    {
        //是否是管理员操作
        if (Auth::user()->is_admin !== '0') {
            $order = Order::find($id);
            $mall_id = $order->mall_id;
            $this->is_mall_manager($mall_id);
        } else {
            $order = Order::where('user_id', Auth::id())->find($id);
        }

        if (is_null($order->pay_time)) {
            return back()->with('success', '确认收货失败！此订单未付款。如果您已经付款，请联系商家确认收款！');
        }
        $update = $order->update(['is_success' => 1]);

        if ($update) {
            return back()->with('success', '确认收货成功!');
        } else {
            return back()->with('success', '确认收货失败!!!!!');
        }
    }

    //删除订单
    public function destroy(Request $request, $id)
    {
        //判断是否从后台发起删除请求
        $order = Order::find($id);
        $is_admin = $request->input('is_admin');
        $mall_id = $order->mall_id;

        //如果是管理员删除 需要检查权限;
        if ($is_admin || ($order->user_id != Auth::id())) {
            $this->is_mall_manager($mall_id);
        }

        if (is_null($order)) {
            return back()->with('success', '订单不存在,可能已经被删除了!!!!');
        }
        //订单未支付并且未收货
        if (is_null($order->pay_time) && $order->is_success === 0) {
            $del = DB::transaction(function () use ($id, $order) {
                $products = json_decode($order->products, true);
                foreach ($products as $product) {
                    $this_product = Product::find($product['product']['id']);
                    //商品存在并且是当天删除的情况下还库存
                    if (!is_null($this_product) && (date("Y-m-d", strtotime($order->created_at)) == date("Y-m-d"))) {
                        $this_product->increment('stock', $product['total_num']);
                    }
                }
                //删除订单
                return Order::destroy($id);
            });

            //删除成功
            if ($del) {
                if ($is_admin) {
                    return back()->with('success', '订单删除成功!');
                }
                return redirect(route('order.index'))->with('success', '订单删除成功!');
            }

            //删除失败
            if (!$del) {
                return back()->with('success', '订单删除失败!!!!!');
            }

        } else {
            return back()->with('success', '订单已经支付或者已经收货，无法删除！！！');
        }
    }

    //导出订单
    public function export_order(Request $request, $id)
    {
        $mall_id = $id;
        $this->is_mall_manager($mall_id);
        $s_id = array();
        if ($request->input('s_id') != '') {
            $s_id = function ($query) use ($request) {
                $query->where('id', $request->input('s_id'));
            };
        }

        //按收货人姓名搜索
        $s_name = array();
        if ($request->input('s_name') != '') {
            $s_name = function ($query) use ($request) {
                $query->where('name', $request->input('s_name'));
            };
        }

        //按收货人电话搜索
        $s_tel = array();
        if ($request->input('s_tel') != '') {
            $s_tel = function ($query) use ($request) {
                $query->where('tel', $request->input('s_tel'));
            };
        }

        //按创建时间搜索
        $c_time = array();
        if ($request->input('created_at') != '') {
            $c_date = str_replace(' ', '', $request->input('created_at'));
            $start_c_date = explode('~', $c_date)[0];
            $end_c_date = explode('~', $c_date)[1];
            $c_time = function ($query) use ($start_c_date, $end_c_date) {
                $query->whereDate('created_at', '>=', $start_c_date)->whereDate('created_at', '<=', $end_c_date);
            };
        }

        //按支付时间搜索
        $p_time = array();
        if ($request->input('pay_date') != '') {
            $p_date = str_replace(' ', '', $request->input('pay_date'));
            $start_p_date = explode('~', $p_date)[0];
            $end_p_date = explode('~', $p_date)[1];
            $p_time = function ($query) use ($start_p_date, $end_p_date) {
                $query->whereDate('pay_time', '>=', $start_p_date)->whereDate('pay_time', '<=', $end_p_date);
            };
        }

        //按支付状态搜索
        $p_state = array();
        if ($request->input('pay_state') == 'y') {
            $p_state = function ($query) use ($request) {
                $query->whereNotNull('pay_time');
            };
        }
        if ($request->input('pay_state') == 'n') {
            $p_state = function ($query) use ($request) {
                $query->whereNull('pay_time');
            };
        }

        //按确认收货搜索
        $success = array();
        if ($request->input('is_success') == 'y') {
            $success = function ($query) use ($request) {
                $query->where('is_success', '=', 1);
            };
        }
        if ($request->input('is_success') == 'n') {
            $success = function ($query) use ($request) {
                $query->where('is_success', '=', 0);
            };
        }

        $orders = Order::with('mall')->where('mall_id', $mall_id)
            ->where($c_time)
            ->where($p_time)
            ->where($p_state)
            ->where($success)
            ->where($s_id)
            ->where($s_name)
            ->where($s_tel)
            ->get();

        foreach ($orders as $key => $value) {
            $pros = json_decode($value->products);
            foreach ($pros as $k => $val) {
                $orders[$key]['pro_text'] .= '[' . $val->product->name . '×' . $val->total_num . ']';
                $orders[$key]['mall_name'] = $value->mall->name;
            }
            unset ($value['mall'], $value['products'], $value['user_id'], $value['deleted_at'], $value['updated_at'], $value['mall_id']);
        }
        return Excel::download(new OrderExport($orders->toArray()), 'order_' . time() . '.xlsx');
    }
}
